﻿using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace CK.Sprite.Core
{
    public class FormCore
    {
        public void TrySetServerParams(JObject method, JArray results)
        {
            if (method["paramModel"] != null && method["paramModel"].ToString() == "server" && method["serverParams"] != null) // 执行服务端方法结果赋值
            {
                var serverParamInfos = method["serverParams"].ToObject<List<ServerParamInfo>>();
                foreach (var serverParamInfo in serverParamInfos)
                {
                    foreach (var result in results)
                    {
                        if (result["ruleId"] != null && result["ruleId"].ToString() == serverParamInfo.ruleId)
                        {
                            var objResult = result["result"];
                            if (!string.IsNullOrEmpty(serverParamInfo.resultFields))
                            {
                                var resultFields = serverParamInfo.resultFields.Split(':');
                                JObject tempJObject = result["result"] as JObject;
                                for (var i = 0; i < resultFields.Length; i++)
                                {
                                    if (tempJObject[resultFields[i]] == null)
                                    {
                                        objResult = null;
                                        break;
                                    }
                                    else
                                    {
                                        objResult = tempJObject[resultFields[i]];
                                    }
                                }
                            }

                            if (!string.IsNullOrEmpty(serverParamInfo.targetFields))
                            {
                                var strTtargetFields = serverParamInfo.targetFields.ToString();
                                if (strTtargetFields.Contains('#'))
                                {
                                    var splitTargetFields = strTtargetFields.Split(new char[] { '#' }, StringSplitOptions.RemoveEmptyEntries);
                                    var splitArrayFields = splitTargetFields[0].Split(':');
                                    JObject tempArrayJObject = method;
                                    for (var i = 0; i < splitArrayFields.Length - 1; i++)
                                    {
                                        if (tempArrayJObject[splitArrayFields[i]] == null)
                                        {
                                            tempArrayJObject.Add(splitArrayFields[i], new JObject());
                                            tempArrayJObject = tempArrayJObject[splitArrayFields[i]] as JObject;
                                        }
                                        else
                                        {
                                            tempArrayJObject = tempArrayJObject[splitArrayFields[i]] as JObject;
                                        }
                                    }
                                    var arrayDatas = tempArrayJObject[splitArrayFields.Last()] as JArray;
                                    foreach (JObject arrayData in arrayDatas)
                                    {
                                        var strServerDictFields = splitTargetFields[1].Split(':');
                                        JObject tempJObject = arrayData;
                                        for (var i = 0; i < strServerDictFields.Length - 1; i++)
                                        {
                                            if (tempJObject[strServerDictFields[i]] == null)
                                            {
                                                tempJObject.Add(strServerDictFields[i], new JObject());
                                                tempJObject = tempJObject[strServerDictFields[i]] as JObject;
                                            }
                                            else
                                            {
                                                tempJObject = tempJObject[strServerDictFields[i]] as JObject;
                                            }
                                        }
                                        if (tempJObject[strServerDictFields.Last()] != null)
                                        {
                                            tempJObject[strServerDictFields.Last()] = objResult;
                                        }
                                        else
                                        {
                                            tempJObject.Add(strServerDictFields.Last(), objResult);
                                        }
                                    }
                                }
                                else
                                {
                                    var strServerDictFields = strTtargetFields.Split(':');
                                    JObject tempJObject = method;
                                    for (var i = 0; i < strServerDictFields.Length - 1; i++)
                                    {
                                        if (tempJObject[strServerDictFields[i]] == null)
                                        {
                                            tempJObject.Add(strServerDictFields[i], new JObject());
                                            tempJObject = tempJObject[strServerDictFields[i]] as JObject;
                                        }
                                        else
                                        {
                                            tempJObject = tempJObject[strServerDictFields[i]] as JObject;
                                        }
                                    }
                                    if (tempJObject[strServerDictFields.Last()] != null)
                                    {
                                        tempJObject[strServerDictFields.Last()] = objResult;
                                    }
                                    else
                                    {
                                        tempJObject.Add(strServerDictFields.Last(), objResult);
                                    }
                                }
                            }
                            else
                            {
                                if (method["datas"] != null)
                                {
                                    method["datas"] = objResult;
                                }
                                else
                                {
                                    method.Add("datas", objResult);
                                }
                            }
                        }
                    }
                }
            }
        }

        private async Task MakeArrayWorkflowInfos(JToken method, JArray arrayInfos, IWorkflowThirdService _workflowThirdService)
        {
            if (method["instanceIdField"] != null && !string.IsNullOrEmpty(method["instanceIdField"].ToString()) && arrayInfos != null)
            {
                var instanceField = method["instanceIdField"].ToString();

                List<string> instanceIds = new List<string>();
                foreach (JObject arrayInfo in arrayInfos)
                {
                    if (arrayInfo.ContainsKey(instanceField))
                    {
                        instanceIds.Add(arrayInfo[instanceField].ToString());
                    }
                }

                var formWorkflowInfos = await _workflowThirdService.GetFormWorkflowInfos(instanceIds);

                foreach (JObject arrayInfo in arrayInfos)
                {
                    var instanceId = arrayInfo[instanceField].ToString();
                    var formWorkflowInfo = formWorkflowInfos.FirstOrDefault(r => r.InstanceId == instanceId);
                    if (formWorkflowInfo != null)
                    {
                        arrayInfo.Add(new JProperty("flow_InstanceId", formWorkflowInfo.InstanceId));
                        arrayInfo.Add(new JProperty("flow_Status", formWorkflowInfo.Status));
                        arrayInfo.Add(new JProperty("flow_CurrentActivities", formWorkflowInfo.CurrentActivities));
                        arrayInfo.Add(new JProperty("flow_InstanceName", formWorkflowInfo.InstanceName));
                        arrayInfo.Add(new JProperty("flow_StartedAt", formWorkflowInfo.StartedAt.HasValue ? formWorkflowInfo.StartedAt.Value.ToString("yyyy-MM-dd HH:mm") : ""));
                        arrayInfo.Add(new JProperty("flow_FinishedAt", formWorkflowInfo.FinishedAt.HasValue ? formWorkflowInfo.FinishedAt.Value.ToString("yyyy-MM-dd HH:mm") : ""));
                    }
                }
            }
        }
    }

    public class ServerParamInfo
    {
        /// <summary>
        /// 如果为空，直接替换datas；如果包含#，则表示列表替换，#前表示哪个参数为列表，#后为替换的Id参数，如果不包含#，表示单个替换
        /// </summary>
        public string targetFields { get; set; }
        public string ruleId { get; set; }
        public string resultFields { get; set; }
    }
}
